home *** CD-ROM | disk | FTP | other *** search
- Path: mail2news.demon.co.uk!genesis.demon.co.uk
- From: Lawrence Kirby <fred@genesis.demon.co.uk>
- Newsgroups: comp.lang.c
- Subject: Re: Q: realloc->free?
- Date: Sat, 20 Jan 96 02:08:34 GMT
- Organization: none
- Message-ID: <822103714snz@genesis.demon.co.uk>
- References: <4df2ud$706@oxy.rust.net> <4dgic7$qin@unix.sri.com> <dan.821890778@handel> <821904243snz@genesis.demon.co.uk> <dan.821977599@handel>
- Reply-To: fred@genesis.demon.co.uk
- X-NNTP-Posting-Host: genesis.demon.co.uk
- X-Newsreader: Demon Internet Simple News v1.27
- X-Mail2News-Path: genesis.demon.co.uk
-
- In article <dan.821977599@handel> dan@bristol.com "J. Daniel Smith" writes:
-
- >In <821904243snz@genesis.demon.co.uk> Lawrence Kirby <fred@genesis.demon.co.uk>
- > writes:
- >>[...]
- >>>adding code to deal for the extremely rare case can add
- >>>significantly to the complexity of the code.
- >
- >>Adding error checking for heap allocation makes minimal difference to
- >>program complexity. OTOH dealing with rare cases properly makes the task
- >>of debugging much easier.
- >
- >Here's an example of what I had in mind
- > void f(const char *string)
- > {
- > static char *buf = NULL;
- >
- > buf = realloc(buf, strlen(string) + 1);
- > /* ... do whatever with buf ... */
- > }
- >Dealing with the realloc() failure makes this
- > void f(const char *string)
- > {
- > static char *buf = NULL;
- > char *tmp;
- >
- > if ((tmp = realloc(buf, strlen(string) + 1)) == NULL)
- > return; /* realloc() failed...now what? */
-
- Well, one thing you know you cannot do is simply continue and use the
- returned value as if it pointed to valid memory. That road leads to
- crashing programs, corrupted data and debugging nightmares.
-
- > buf = tmp;
- > /* ... do whatever with buf ... */
- > }
- >This prevents a crash, and in that respect it is definately more
- >robust than not checking realloc()'s return value. But does the
- >program still run correctly? Not likely, since whatever f() was
- >supposed to do isn't being done.
-
- Clearly of the rest of the program expects f() to have done something
- it cannot simply return not having done it.
-
- >
- >One could make all kinds of arguments about return values, error codes,
- >poor software design, whatever. And I'll agree that things would be
- >better if f() were written as follows
- > int f(const char *string)
- > {
- > static char *buf = NULL;
- > char *tmp;
- >
- > if ((tmp = realloc(buf, strlen(string) + 1)) == NULL)
- > return 0; /* realloc() failed */
- > buf = tmp;
- > /* ... do whatever with buf ... */
- >
- > return 1;
- > }
- >but in real life, this sometimes isn't an option.
-
- Can you give an example where returning a success condition in some form
- or another can't be used?
-
- >>> And if realloc() does
- >>>fail, there are probably a lot bigger things to worry about than
- >>>leaking memory (like the GUI not being able to create a window to tell
- >>>you something has went wrong).
- >>
- >>You can at the very least exit cleanly at the point of failure. If you fail
- >>in allocation you can try to creewate an error window and exit cleanly
- >>if that fails.
- >
- >yes, this is nicer than crashing and leaving a core dump, or getting a
- >GPF dialog box. But a GUI application suddenly quitting for no
- >apparent reason isn't very nice either.
-
- It is much better than it locking up, corrupting the rest of the system or
- your data files for no apparent reason. A way can usually be found to
- log some sort of diagnostic. A reasonable OS would be able to log events
- such as refusing memory allocation to a program. 'Out of memory' is
- something tht can usually be corrected relatively simply and the program
- rerun.
-
- >>>Yes, the programmer needs to be aware of the fact that realloc() can
- >>>fail, but in some cases ALWAYS checking the return value of realloc()
- >>>just isn't practical given other constraints.
- >>
- >>I can't think of any reasonable constraints that would make it impractical.
- >
- >the function above is burried 15 calls deep, many of the functions in
- >the call chain have no provisions for checking return values. As you
- >say, calling exit() will at least terminate cleanly, but now I've got
- >calls to exit() (or my own fatal_exit()) scattered all through my
- >program which some might say is poor style.
-
- Only because proper error handling is better style. This 'poor style' is
- still a vastly better style than not checking for error conditions at all.
-
- >My only real contention is with "ALWAYS" - I don't like absolutes. :-)
-
- I think this is one you should learn to love! :-)
-
- --
- -----------------------------------------
- Lawrence Kirby | fred@genesis.demon.co.uk
- Wilts, England | 70734.126@compuserve.com
- -----------------------------------------
-